﻿using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Windows;
using System.Windows.Controls;
using Burglar.Controls;
using Burglar.MailingService;
using WinForms = System.Windows.Forms;

namespace Burglar
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        MessageListener _listener;
        MailingClient _client;
        WinForms.NotifyIcon notifier = new WinForms.NotifyIcon();

        public static readonly RoutedEvent PalaceAdedEvent = EventManager.RegisterRoutedEvent(
        "PalaceAded", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(MainWindow));

        public static readonly RoutedEvent PalaceRemovedEvent = EventManager.RegisterRoutedEvent(
        "PalaceRemoved", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(MainWindow));

        public event RoutedEventHandler PalaceAded
        {
            add { AddHandler(PalaceAdedEvent, value); }
            remove { RemoveHandler(PalaceAdedEvent, value); }
        }
        public event RoutedEventHandler PalaceRemoved
        {
            add { AddHandler(PalaceRemovedEvent, value); }
            remove { RemoveHandler(PalaceRemovedEvent, value); }
        }

        public MainWindow()
        {
            InitializeComponent();
            InitListener();
            var instance = new InstanceContext(_listener);
            _client = new MailingClient(instance);
            InitExistingPalaces(_client.Subscribe(Environment.UserDomainName));
            var desktopWorkingArea = SystemParameters.WorkArea;
            Left = desktopWorkingArea.Right - Width;
            Top = desktopWorkingArea.Bottom - Height;

            notifier.MouseDown += notifier_MouseDown;
            notifier.Icon = Properties.Resources.IntelliTrace;
            notifier.Visible = true;

        }

        private void InitExistingPalaces(IEnumerable<Palace> palaces)
        {
            foreach (var palace in palaces){
                PalaceToPanel(palace);
            }
        }

        void notifier_MouseDown(object sender, WinForms.MouseEventArgs e)
        {
            if (e.Button == WinForms.MouseButtons.Right)
            {
                var menu = (ContextMenu)FindResource("NotifierContextMenu");
                menu.IsOpen = true;
            }
        }

        private void Menu_Settings(object sender, RoutedEventArgs e)
        {
            var form = new SettingsForm();
            form.Show();

        }

        private void Menu_Close(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void InitListener()
        {
            _listener = new MessageListener();
            _listener.OnActivity += OnActivity;
            _listener.OnPalaceAdd += OnPalaceAdd;
            _listener.OnPalaceRemove += OnPalaceRemove;
            _listener.OnBurglarChange += OnBurglarChange;
        }

        private void OnBurglarChange(object sender, InvasionAlertEventArgs args)
        {
            try
            {
                foreach (var child in PalacesStackPanel.Children)
                {
                    var palacePanel = child as PalacePanel;
                    if (palacePanel != null &&
                        palacePanel.PalaceName.Equals(args.Alert.Palace.Name))
                    {
                        palacePanel.BurglarName = args.Alert.Palace.Burglar.Name;
                        break;
                    }
                }

            }
            catch (Exception)
            {

            }
        }

        private void OnPalaceRemove(object sender, PalaceEventArgs args)
        {
            try
            {
                foreach (var child in PalacesStackPanel.Children)
                {
                    var palacePanel = child as PalacePanel;
                    if (palacePanel != null && 
                        palacePanel.PalaceName.Equals(args.Palace.Name))
                    {
                        PalacesStackPanel.Children.Remove(palacePanel);
                        RaiseEvent(new RoutedEventArgs(PalaceRemovedEvent));

                        break;
                    }
                }
            }
            catch (Exception)
            {

            }
        }

        private void OnPalaceAdd(object sender, PalaceEventArgs args)
        {
            PalaceToPanel(args.Palace);
        }

        private void PalaceToPanel(Palace palace)
        {
            if (!PalaceInList(palace.Name)){
                var panel = new PalacePanel(palace.Name);
                PalacesStackPanel.Children.Add(panel);
                RaiseEvent(new RoutedEventArgs(PalaceAdedEvent));
            }
        }


        private bool PalaceInList(string pName)
        {
            foreach (var child in PalacesStackPanel.Children)
            {
                var palacePanel = child as PalacePanel;
                if (palacePanel.PalaceName.Equals(pName))
                    return true;
            }
            return false;
        }

        private void OnActivity(object sender, PalaceActivityEventArgs args)
        {
            try
            {
                foreach (var child in PalacesStackPanel.Children)
                {
                    var palacePanel = child as PalacePanel;
                    if (palacePanel != null && 
                        palacePanel.PalaceName.Equals(args.Activity.Palace.Name))
                    {
                        palacePanel.ActivityName = args.Activity.Name;

                        break;
                    }
                }
            }
            catch (Exception)
            {

            }
        }

        private void PalacesWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            try
            {

            _client.UnsubscribeAsync();
            _client.Close();
            }
            catch (Exception)
            {
                
            }
        }
    }
}
